﻿/*** MikeWare Framework ************************************
* This class is part of product of MikeWare.Framework.
* 
* Author      : Mike Cheers
* Mail        : mikecheers@126.com
* Create Date : 2018/9/14
* Summary     : 
* 
* 
* Modified By : 
* Date        : 
* Mail        : 
* Comment     : 
**************************************************************/

namespace MikeWare.Components.MikeLoggor
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Text.RegularExpressions;

    public class SettingsReader
    {
        public static IList<Settings> Read(String settingsFilePath)
        {
            var settings = new List<Settings>();

            using (StreamReader reader = new StreamReader(settingsFilePath))
            {
                Stack<Settings> stack = null;

                while (!reader.EndOfStream)
                {
                    var line = reader.ReadLine();
                    var trimline = line.Trim();
                    if (string.IsNullOrEmpty(trimline)) continue;
                    if (trimline.StartsWith("#")) continue;

                    var current = ReadSetting(line);
                    if (null == current) continue;

                    if (null == stack)
                    {
                        stack = new Stack<Settings>();
                        stack.Push(current);
                        settings.Add(current);
                    }
                    else
                    {
                        var hasParent = false;
                        do
                        {
                            var parent = stack.Pop();
                            if (1 == current.IdentLevel - parent.IdentLevel)
                            {
                                if (null == parent.Childen) parent.Childen = new List<Settings>();
                                parent.Childen.Add(current);
                                stack.Push(parent);
                                stack.Push(current);
                                hasParent = true;
                                break;
                            }
                        } while (stack.Count > 0);

                        if (!hasParent)
                        {
                            stack.Push(current);
                            settings.Add(current);
                        }
                    }
                }
            }

            return settings;
        }

        private static Settings ReadSetting(string line)
        {
            var setting = new Settings();
            var array = line.Split(":".ToCharArray(), 2, StringSplitOptions.None);
            if (array.Length > 0) setting.Name = array[0].Trim();
            else return null;
            if (array.Length > 1) setting.Value = ReplaceEnvironmentVariables(array[1].Trim());
            setting.IdentLevel = line.Length - line.TrimStart("\t".ToCharArray()).Length;

            return setting;
        }

        internal static string ReplaceEnvironmentVariables(string value)
        {
            var variablePattern = @"%e\{(?<var>[^}]+?)}";
            Regex regex = new Regex(variablePattern);
            var matches = regex.Matches(value);
            if (null == matches || 0 == matches.Count) return value;

            foreach (Match match in matches)
            {
                var variable = match.Groups["var"].Value;
                var matchPattern = @"%e\{" + variable + @"}";
                switch (variable.Trim().ToUpper())
                {
                    case "CURRENTDIRECTORY":
                        value = Regex.Replace(value, matchPattern, Environment.CurrentDirectory);
                        break;
                    default:
                        break;
                }
            }

            return value;
        }
    }
}
